﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using Pap.Data.Abstraction.Utils;

namespace Pap.Data.LToS
{
    /// <summary>
    /// 
    /// </summary>
    public partial class Database : IDatabase, IWorkFlow
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Database"/> class.
        /// </summary>
        /// <param name="ConnectionString">The connection string.</param>
        public Database(ConnectionStrings ConnectionString)
            : this(ConnectionString.ConnectionString1)
        {

        }

        /// <summary>
        /// Gets the loan feasibility studies.
        /// </summary>
        public IQueryable<ILoanFeasibilityStudy> LoanFeasibilityStudies
        {
            get { return this.LoanFeasabilityStudies.OfType<ILoanFeasibilityStudy>(); }
        }

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="entity">The entity.</param>
        public void Delete<TEntity>(TEntity entity) where TEntity : IEntity
        {
            this.GetTable(entity.GetType()).DeleteOnSubmit(entity);
        }

        /// <summary>
        /// Deletes all.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="entities">The entities.</param>
        public void DeleteAll<TEntity>(IEnumerable<TEntity> entities) where TEntity : IEntity
        {
            this.GetTable(GetTypeFromIEntity<TEntity>()).DeleteAllOnSubmit(entities);
        }

        /// <summary>
        /// Inserts the specified entity.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="entity">The entity.</param>
        public void Insert<TEntity>(TEntity entity) where TEntity : IEntity
        {
            this.GetTable(entity.GetType()).InsertOnSubmit(entity);
        }

        /// <summary>
        /// Inserts all.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="entities">The entities.</param>
        public void InsertAll<TEntity>(IEnumerable<TEntity> entities) where TEntity : IEntity
        {
            Type currentType = GetTypeFromIEntity<TEntity>();
            //--------------------------------------------------------
            this.GetTable(currentType).InsertAllOnSubmit(entities);
        }

        /// <summary>
        /// Gets the type from I entity.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <returns></returns>
        private Type GetTypeFromIEntity<TEntity>() where TEntity : IEntity
        {
            Type currentType = null;
            foreach (var property in this.GetType().GetProperties())
            {
                if (property.PropertyType.IsGenericType)
                {
                    if (typeof(ITable).IsAssignableFrom(property.PropertyType))
                    {
                        currentType = property.PropertyType.GetGenericArguments()[0];
                        if (typeof(TEntity).IsAssignableFrom(currentType))
                            break;
                    }
                }
            }
            return currentType;
        }

        /// <summary>
        /// Gets the board attendees.
        /// </summary>
        IQueryable<IBoardAttendee> IDatabase.BoardAttendees
        {
            get
            {
                return this.BoardAttendees.OfType<IBoardAttendee>();
            }
        }

        IQueryable<IUsersRole> IDatabase.UsersRole
        {
            get
            {
                return this.UsersRoles.OfType<IUsersRole>();
            }
        }

        IQueryable<IRolesPermission> IDatabase.RolesPermission
        {
            get
            {
                return this.RolesPermissions.OfType<IRolesPermission>();
            }
        }

        /// <summary>
        /// Gets the users.
        /// </summary>
        IQueryable<IUser> IDatabase.Users
        {
            get
            {
                return this.Users.OfType<IUser>();
            }
        }

        /// <summary>
        /// Gets the roles.
        /// </summary>
        IQueryable<IRole> IDatabase.Roles
        {
            get
            {
                return this.Roles.OfType<IRole>();
            }
        }

        /// <summary>
        /// Gets the permissions.
        /// </summary>
        IQueryable<IPermission> IDatabase.Permissions
        {
            get
            {
                return this.Permissions.OfType<IPermission>();
            }
        }

        /// <summary>
        /// Gets the villages.
        /// </summary>
        IQueryable<IVillage> IDatabase.Villages
        {
            get
            {
                return this.Villages.OfType<IVillage>();
            }
        }

        /// <summary>
        /// Gets the committees.
        /// </summary>
        IQueryable<ICommittee> IDatabase.Committees
        {
            get
            {
                return this.Committees.OfType<ICommittee>();
            }
        }
        /// <summary>
        /// Gets the committees URL.
        /// </summary>
        IQueryable<ICommitteesURL> IDatabase.CommitteesURL
        {
            get
            {
                return this.CommitteesURLs.OfType<ICommitteesURL>();
            }
        }

        /// <summary>
        /// Gets the settings.
        /// </summary>
        IQueryable<ISetting> IDatabase.Settings
        {
            get
            {
                return this.Settings.OfType<ISetting>();
            }
        }

        /// <summary>
        /// Gets the centers.
        /// </summary>
        IQueryable<ICenter> IDatabase.Centers
        {
            get
            {
                return this.Centers.OfType<ICenter>();
            }
        }

        /// <summary>
        /// Gets the projects.
        /// </summary>
        IQueryable<IProject> IDatabase.Projects
        {
            get
            {
                return this.Projects.OfType<IProject>();
            }
        }

        /// <summary>
        /// Gets the project stages.
        /// </summary>
        IQueryable<IProjectStage> IDatabase.ProjectStages
        {
            get { return this.ProjectStages.OfType<IProjectStage>(); }
        }

        /// <summary>
        /// Gets the customers.
        /// </summary>
        IQueryable<ICustomer> IDatabase.Customers
        {
            get { return this.Customers.OfType<ICustomer>(); }
        }

        /// <summary>
        /// Gets the images.
        /// </summary>
        IQueryable<IImage> IDatabase.Images
        {
            get { return this.Images.OfType<IImage>(); }
        }

        /// <summary>
        /// Gets the customer loan histories.
        /// </summary>
        IQueryable<ICustomerLoanHistory> IDatabase.CustomerLoanHistories
        {
            get { return this.CustomerLoanHistories.OfType<ICustomerLoanHistory>(); }
        }

        /// <summary>
        /// Gets the issue places.
        /// </summary>
        IQueryable<IIssuePlace> IDatabase.IssuePlaces
        {
            get { return this.IssuePlaces.OfType<IIssuePlace>(); }
        }

        /// <summary>
        /// Gets the customer loans.
        /// </summary>
        IQueryable<ICustomerLoan> IDatabase.CustomerLoans
        {
            get { return this.CustomerLoans.OfType<ICustomerLoan>(); }
        }

        /// <summary>
        /// Gets the governorates.
        /// </summary>
        IQueryable<IGovernorate> IDatabase.Governorates
        {
            get { return this.Governorates.OfType<IGovernorate>(); }
        }

        /// <summary>
        /// Gets the social statuses.
        /// </summary>
        IQueryable<ILookUpEntity> IDatabase.SocialStatuses
        {
            get { return this.SocialStatuses.OfType<ILookUpEntity>(); }
        }

        /// <summary>
        /// Gets the educational levels.
        /// </summary>
        IQueryable<ILookUpEntity> IDatabase.EducationalLevels
        {
            get { return this.EducationalLevels.OfType<ILookUpEntity>(); }
        }

        /// <summary>
        /// Gets the loan place types.
        /// </summary>
        IQueryable<ILookUpEntity> IDatabase.LoanPlaceTypes
        {
            get { return this.LoanPlaceTypes.OfType<ILookUpEntity>(); }
        }

        /// <summary>
        /// Gets the loan types.
        /// </summary>
        IQueryable<ILookUpEntity> IDatabase.LoanTypes
        {
            get { return this.LoanTypes.OfType<ILookUpEntity>(); }
        }

        /// <summary>
        /// Gets the loan payment method.
        /// </summary>
        IQueryable<ILoanPaymentMethod> IDatabase.LoanPaymentMethod
        {
            get { return this.LoanPaymentMethods.OfType<ILoanPaymentMethod>(); }
        }

        /// <summary>
        /// Gets the military statuses.
        /// </summary>
        IQueryable<ILookUpEntity> IDatabase.MilitaryStatuses
        {
            get { return this.MilitaryStatuses.OfType<ILookUpEntity>(); }
        }

        /// <summary>
        /// Gets the loan legal forms.
        /// </summary>
        IQueryable<ILookUpEntity> IDatabase.LoanLegalForms
        {
            get { return this.LoanLegalForms.OfType<ILookUpEntity>(); }
        }

        /// <summary>
        /// Gets the type of the loan history close.
        /// </summary>
        /// <value>
        /// The type of the loan history close.
        /// </value>
        IQueryable<ILookUpEntity> IDatabase.LoanHistoryCloseType
        {
            get { return this.LoanHistoryCloseTypes.OfType<ILookUpEntity>(); }
        }

        /// <summary>
        /// Gets the wf process instances.
        /// </summary>
        IQueryable<IwfProcessInstance> IWorkFlow.wfProcessInstances
        {
            get { return this.wfProcessInstances.OfType<IwfProcessInstance>(); }
        }

        /// <summary>
        /// Gets the wf step instances.
        /// </summary>
        IQueryable<IwfStepInstance> IWorkFlow.wfStepInstances
        {
            get { return this.wfStepInstances.OfType<IwfStepInstance>(); }
        }

        /// <summary>
        /// Gets the wf steps.
        /// </summary>
        IQueryable<IwfStep> IWorkFlow.wfSteps
        {
            get { return this.wfSteps.OfType<IwfStep>(); }
        }

        /// <summary>
        /// Gets the image types.
        /// </summary>
        IQueryable<ILookUpEntity> IDatabase.ImageTypes
        {
            get { return this.ImageTypes.OfType<ILookUpEntity>(); }
        }

        /// <summary>
        /// Gets the boards.
        /// </summary>
        IQueryable<IBoard> IDatabase.Boards
        {
            get { return this.Boards.OfType<IBoard>(); }
        }

        /// <summary>
        /// Gets the board loans.
        /// </summary>
        IQueryable<IBoardLoan> IDatabase.BoardLoans
        {
            get { return this.BoardLoans.OfType<IBoardLoan>(); }
        }

        /// <summary>
        /// Gets the loan feasibility study attachments.
        /// </summary>
        public IQueryable<ILoanFeasibilityStudyAttachment> LoanFeasibilityStudyAttachments
        {
            get
            {
                return this.LoanFeasabilityStudyAttachments.OfType<ILoanFeasibilityStudyAttachment>();
            }
        }

        /// <summary>
        /// Gets the loan social researches.
        /// </summary>
        IQueryable<ILoanSocialResearch> IDatabase.LoanSocialResearches
        {
            get { return this.LoanSocialResearches.OfType<ILoanSocialResearch>(); }
        }

        /// <summary>
        /// Gets the loan social research attachments.
        /// </summary>
        IQueryable<ILoanSocialResearchAttachment> IDatabase.LoanSocialResearchAttachments
        {
            get { return this.LoanSocialResearchAttachments.OfType<ILoanSocialResearchAttachment>(); }
        }

        /// <summary>
        /// Gets the user messages.
        /// </summary>
        IQueryable<IUserMessage> IDatabase.UserMessages
        {
            get { return this.UserMessages.OfType<IUserMessage>(); }
        }

        /// <summary>
        /// Gets the board attachments.
        /// </summary>
        IQueryable<IBoardAttachment> IDatabase.BoardAttachments
        {
            get { return this.BoardAttachments.OfType<IBoardAttachment>(); }
        }

        /// <summary>
        /// Gets the receipts.
        /// </summary>
        IQueryable<IReceipt> IDatabase.Receipts
        {
            get { return this.Receipts.OfType<IReceipt>(); }
        }


        /// <summary>
        /// Gets the loan executions.
        /// </summary>
        IQueryable<ILoanExecution> IDatabase.LoanExecutions
        {
            get { return this.LoanExecutions.OfType<ILoanExecution>(); }
        }

        /// <summary>
        /// Gets the loan executions attachmens.
        /// </summary>
        IQueryable<ILoanExecutionAttachment> IDatabase.LoanExecutionsAttachmens
        {
            get { return this.LoanExecutionAttachments.OfType<ILoanExecutionAttachment>(); }
        }

        /// <summary>
        /// Gets the loan execution installments.
        /// </summary>
        IQueryable<ILoanExecutionInstallment> IDatabase.LoanExecutionInstallments
        {
            get { return this.LoanExecutionInstallments.OfType<ILoanExecutionInstallment>(); }
        }

        /// <summary>
        /// Gets the loan installment payments.
        /// </summary>
        IQueryable<ILoanInstallmentPayment> IDatabase.LoanInstallmentPayments
        {
            get { return this.LoanInstallmentPayments.OfType<ILoanInstallmentPayment>(); }
        }


        /// <summary>
        /// Gets the committee bank accounts.
        /// </summary>
        IQueryable<ICommitteeBankAccount> IDatabase.CommitteeBankAccounts
        {
            get { return this.CommitteeBankAccounts.OfType<ICommitteeBankAccount>(); }
        }

        /// <summary>
        /// Gets the committee bank account deposites.
        /// </summary>
        IQueryable<ICommitteeBankAccountDeposite> IDatabase.CommitteeBankAccountDeposites
        {
            get { return this.CommitteeBankAccountDeposites.OfType<ICommitteeBankAccountDeposite>(); }
        }

        /// <summary>
        /// Gets the committee bank account deposit attachments.
        /// </summary>
        IQueryable<ICommitteeBankAccountDepositAttachment> IDatabase.CommitteeBankAccountDepositAttachments
        {
            get { return this.CommitteeBankAccountDepositAttachments.OfType<ICommitteeBankAccountDepositAttachment>(); }
        }

        /// <summary>
        /// Gets the committee bank account deposit receipts.
        /// </summary>
        IQueryable<ICommitteeBankAccountDepositReceipt> IDatabase.CommitteeBankAccountDepositReceipts
        {
            get { return this.CommitteeBankAccountDepositReceipts.OfType<ICommitteeBankAccountDepositReceipt>(); }
        }

        /// <summary>
        /// Gets the committee bank account expenses.
        /// </summary>
        IQueryable<ICommitteeBankAccountExpense> IDatabase.CommitteeBankAccountExpenses
        {
            get { return this.CommitteeBankAccountExpenses.OfType<ICommitteeBankAccountExpense>(); }
        }

        /// <summary>
        /// Gets the committee bank account main branch deposit attachments.
        /// </summary>
        IQueryable<ICommitteeBankAccountMainBranchDepositAttachment> IDatabase.CommitteeBankAccountMainBranchDepositAttachments
        {
            get { return this.CommitteeBankAccountMainBranchDepositAttachments.OfType<ICommitteeBankAccountMainBranchDepositAttachment>(); }
        }

        /// <summary>
        /// Gets the committee bank account main branch deposites.
        /// </summary>
        IQueryable<ICommitteeBankAccountMainBranchDeposite> IDatabase.CommitteeBankAccountMainBranchDeposites
        {
            get { return this.CommitteeBankAccountMainBranchDeposites.OfType<ICommitteeBankAccountMainBranchDeposite>(); }
        }

        /// <summary>
        /// Gets the loan installment warnings.
        /// </summary>
        IQueryable<ILoanInstallmentWarning> IDatabase.LoanInstallmentWarnings
        {
            get { return this.LoanIntstallmentWarnings.OfType<ILoanInstallmentWarning>(); }
        }

        /// <summary>
        /// Gets the loan installment warning attachments.
        /// </summary>
        IQueryable<ILoanInstallmentWarningAttachment> IDatabase.LoanInstallmentWarningAttachments
        {
            get { return this.LoanInstallmentWarningAttachments.OfType<ILoanInstallmentWarningAttachment>(); }
        }

        /// <summary>
        /// Gets the loan cases.
        /// </summary>
        IQueryable<ILoanCase> IDatabase.LoanCases
        {
            get { return this.LoanCases.OfType<ILoanCase>(); }
        }

        /// <summary>
        /// Gets the loan cancelling debts.
        /// </summary>
        IQueryable<ILoanCancellingDebt> IDatabase.LoanCancellingDebts
        {
            get { return this.LoanCancellingDebts.OfType<ILoanCancellingDebt>(); }
        }

        /// <summary>
        /// Gets the loan cancelling debt attachments.
        /// </summary>
        IQueryable<ILoanCancellingDebtAttachment> IDatabase.LoanCancellingDebtAttachments
        {
            get { return this.LoanCancellingDebtAttachments.OfType<ILoanCancellingDebtAttachment>(); }
        }

        /// <summary>
        /// Gets the V users transactions.
        /// </summary>
        IQueryable<IVUsersTransaction> IDatabase.VUsersTransactions
        {
            get { return this.VUsersTransactions.OfType<IVUsersTransaction>(); }
        }

        /// <summary>
        /// Gets the V monthly accountant report.
        /// </summary>
        IQueryable<IVMonthlyAccountantReport> IDatabase.VMonthlyAccountantReport
        {
            get { return this.VMonthlyAccountantReports.OfType<IVMonthlyAccountantReport>(); }
        }


        /// <summary>
        /// Gets the board members.
        /// </summary>
        IQueryable<IBoardMember> IDatabase.BoardMembers
        {
            get { return this.BoardMembers.OfType<IBoardMember>(); }
        }


        /// <summary>
        /// Gets the board members.
        /// </summary>
        IQueryable<IUsersProject> IDatabase.UsersProjects
        {
            get { return this.UsersProjects.OfType<IUsersProject>(); }
        }

        #region IDatabase Members


        /// <summary>
        /// Gets the main committee deposits.
        /// </summary>
        IQueryable<IMainCommitteeDeposit> IDatabase.MainCommitteeDeposits
        {
            get { return this.MainCommitteeDeposits.OfType<IMainCommitteeDeposit>(); }
        }

        #endregion

        #region IDatabase Members


        /// <summary>
        /// Gets the main committee expenses.
        /// </summary>
        IQueryable<IMainCommitteeExpense> IDatabase.MainCommitteeExpenses
        {
            get { return this.MainCommitteeExpenses.OfType<IMainCommitteeExpense>(); }
        }

        #endregion





        /// <summary>
        /// Gets the V monthly responsible report.
        /// </summary>
        IQueryable<IVMonthlyResponsibleReport> IDatabase.VMonthlyResponsibleReport
        {
            get { return this.VMonthlyResponsibleReports.OfType<IVMonthlyResponsibleReport>(); }
        }


        /// <summary>
        /// Gets the V waiting list report.
        /// </summary>
        IQueryable<IVWaitingListReport> IDatabase.VWaitingListReport
        {
            get { return this.VWaitingListReports.OfType<IVWaitingListReport>(); }
        }


        /// <summary>
        /// Gets the V total system report.
        /// </summary>
        IQueryable<IVTotalSystemReport> IDatabase.VTotalSystemReport
        {
            get { return this.VTotalSystemReports.OfType<IVTotalSystemReport>(); }
        }
    }

}
